/*
 Copyright 2009 Abdulla Abdurakhmanov (abdulla@latestbit.com)
 Original sources are available at www.latestbit.com

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.

 ServerInstancesRegistry.hpp. Created on: 15.10.2009 12:04:46 
 */

#ifndef SERVERINSTANCESREGISTRY_HPP_
#define SERVERINSTANCESREGISTRY_HPP_

#include "smartobjects/SmartObjectsDefs.hpp"
#include "smartobjects/core/IServerInstancesRegistry.hpp"
#include "smartobjects/IServerSkeleton.hpp"
#include "smartobjects/network/ConnectionHandler.hpp"
#include "smartobjects/network/IConnectionListener.hpp"

namespace smartobjects {

class ServerInstancesRegistry : public IServerInstancesRegistry, protected IConnectionListener {
public:
	SO_DLLPRFX ServerInstancesRegistry();
	SO_DLLPRFX virtual ~ServerInstancesRegistry();

	SO_DLLPRFX virtual void addInstance ( IServerSkeleton* poInstance );
	SO_DLLPRFX virtual void attachInstanceClientHandler ( ConnectionHandler* poHandler, IServerSkeleton* poInstance );
	SO_DLLPRFX virtual void detachInstanceClientHandler ( ConnectionHandler* poHandler, IServerSkeleton* poInstance );
	SO_DLLPRFX virtual void removeInstance ( IServerSkeleton* poInstance );

	SO_DLLPRFX virtual void addListener ( IServerInstancesRegistryListener* poListener );
	SO_DLLPRFX virtual void delListener ( IServerInstancesRegistryListener* poListener );

	SO_DLLPRFX virtual int getInstancesCount();

	SO_DLLPRFX virtual void setTimerWakeUpInterval ( unsigned long nIntervalInSec );
	SO_DLLPRFX virtual unsigned long getTimerWakeUpInterval ();
protected:
	const static unsigned long DEFAULT_TIMER_WAKE_UP_INTERVAL;

protected:
	SO_DLLPRFX virtual void onDisconnected(IConnection* poConnection) throw();
	SO_DLLPRFX virtual void onTimer(Timer::TimerId nTimerId);
	SO_DLLPRFX virtual void fireOnRegister(IServerSkeleton* poSkeleton);
	SO_DLLPRFX virtual void fireOnUnregister(IServerSkeleton* poSkeleton);
	SO_DLLPRFX virtual void processingPostActionAvailabilityListeners();

protected:
	typedef std::set< IServerSkeleton* > InstancesSet;
	InstancesSet m_aInstances;

	typedef boost::bimap < boost::bimaps::unordered_multiset_of <IConnection*>, boost::bimaps::unordered_multiset_of <IServerSkeleton*> > InstancesPerConnectionMap;
	InstancesPerConnectionMap m_mInstancesPerConnection;

	boost::recursive_mutex m_mxInstances;
	Timer* m_poTimer;
	unsigned long m_nTimerWakeUpInterval;
	bool m_bHasInstancesByTime;


	typedef std::list<IServerInstancesRegistryListener*> RegistryListeners;
	RegistryListeners m_aRegistryListeners;
	PostActionListenersContainer<IServerInstancesRegistryListener> m_oPALRegistryListeners;
	boost::recursive_mutex m_mxRegistryListeners;

};

}

#endif /* SERVERINSTANCESREGISTRY_HPP_ */
